package com.ar4j;

import javax.sql.DataSource;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;

import com.ar4j.sql.INamedQuerySource;

/**
 * The context in which active records execute their operations
 */
public class ActiveRecordContext {
  private DataSource dataSource;
  private SimpleJdbcTemplate simpleTemplate;
  private INamedQuerySource namedQuerySource;
  private PlatformTransactionManager platformTransactionManager;
  private String schemaName;
  
  private int hashCode;
  
  public ActiveRecordContext(DataSource dataSource, String schemaName, INamedQuerySource namedQuerySource, PlatformTransactionManager platformTransactionManager) {
    if(dataSource == null) {
      throw new IllegalArgumentException("Must have a datasource");
    }
    
    this.dataSource = dataSource;
    this.simpleTemplate = new SimpleJdbcTemplate(dataSource);
    this.namedQuerySource = namedQuerySource;
    this.platformTransactionManager = platformTransactionManager;
    this.schemaName = schemaName;
    
    this.hashCode = HashCodeBuilder.reflectionHashCode(this);
  }
  
  public ActiveRecordContext(DataSource dataSource) {
    this(dataSource, null, null, null);
  }
  
  public ActiveRecordContext(DataSource dataSource, PlatformTransactionManager platformTransactionManager) {
    this(dataSource, null, null, platformTransactionManager);
  }
  
  public ActiveRecordContext(DataSource dataSource, INamedQuerySource namedQuerySource, PlatformTransactionManager platformTransactionManager) {
    this(dataSource, null, namedQuerySource, platformTransactionManager);
  }

  public DataSource getDataSource() {
    return dataSource;
  }

  public SimpleJdbcTemplate getSimpleTemplate() {
    return simpleTemplate;
  }
  
  public INamedQuerySource getNamedQuerySource() {
    return namedQuerySource;
  }

  public PlatformTransactionManager getPlatformTransactionManager() {
    return platformTransactionManager;
  }

  public String getSchemaName() {
    return schemaName;
  }
  
  @Override
  public int hashCode() {
    return hashCode;
  }
  
  @Override
  public boolean equals(Object o) {
    return EqualsBuilder.reflectionEquals(this, o);
  }

  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
  }
  
}
